-module(rtps_endpoint_sup).

-behaviour(supervisor).

%% API
-export([start_link/4, history_cache/1]).

%% Supervisor callbacks
-export([init/1]).

%%====================================================================
%% API functions
%%====================================================================

-spec history_cache(Sup) -> {ok, Child} | {error, Reason} when                  
      Sup :: pid(),                                                             
      Child :: pid(),                                                           
      Reason :: notfound | restarting.                                          
history_cache(Sup) ->                                                           
    Children = supervisor:which_children(Sup),                                  
    
    {_Id, Child, _Type, _Modules} = lists:keyfind(history_cache, 1, Children),
    case is_pid(Child) of
	true ->
	    {ok, Child};
	false ->
	    {error, Child}
    end.

start_link(Kind, Entity_id, Reg, Opts) ->
    supervisor:start_link(?MODULE, [Kind, Entity_id, Reg, Opts]).

%%====================================================================
%% Supervisor callbacks
%%====================================================================

%% @private
init([Kind, Entity_id, Reg, Opts]) ->
    Opts1 = [{entity_id, Entity_id} | Opts],
    Module = case Kind of
		 writer ->
		     rtps_writer;
		 reader ->
		     rtps_reader
	     end,
    Specs1 = [#{id => registry,
		start => {rtps_reg, start_link, []},
		restart => permanent,
		type => worker}],
    Specs2 = case proplists:get_value(history_cache, Opts1) of
		 undefined ->
		     Specs1 ++ [#{id => history_cache,
				  start => {rtps_history_cache, start_link, [Opts1]},
				  restart => permanent,
				  type => worker}];
		 _Pid ->
		     Specs1
	     end,
    Specs3 = case proplists:get_value(state_type, Opts1) of
		 %% A stateless reader will accept incoming cache
		 %% changes directly and not use an intermediate
		 %% process, so there is no need to add a supervisor
		 %% here.
		 stateless when Kind =/= reader ->
		     Specs2 ++ [#{id => locators,
				  start => {rtps_ofo_sup, start_link, []},
				  restart => permanent,
				  type => supervisor}];
		 stateful ->
		     Specs2 ++ [#{id => proxies,
				  start => {rtps_ofo_sup, start_link, []},
				  restart => permanent,
				  type => supervisor}];
		 _ ->
		     Specs2
	     end,
    Specs4 = Specs3 ++ 
	[#{id => endpoint,
	   start => {Module, start_link, [self(), Entity_id, Reg, Opts1]},
	   restart => permanent,
	   type => worker}],

    {ok, {#{strategy => one_for_all}, Specs4}}.

%%====================================================================
%% Internal functions
%%====================================================================

